﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using System.Diagnostics;

namespace FishServe.Core
{
	public class ManifestModuleInfo
	{
		private string _name;
		private string _guid;
		private Version _version;
		private string _culture;
		private ModuleManifestType _type;
		private string _publicKeyToken = String.Empty;
		private string _manifestGuid = String.Empty;
		private string _category = String.Empty;
		private string _description = String.Empty;
		private string _fileHash = String.Empty;

		public string Name
		{
			get { return _name; }
		}

		public string Guid
		{
			get { return _guid; }
		}

		public Version Version
		{
			get { return _version; }
		}

		public string Culture
		{
			get { return _culture; }
		}

		public string PublicKeyToken
		{
			get { return _publicKeyToken; }
		}

		public string ManifestGuid
		{
			get { return _manifestGuid; }
		}

		public string Category
		{
			get { return _category; }
			// TODO review access
			set { _category = value; }
		}

		public string Description
		{
			get { return _description; }
			// TODO review access
			set { _description = value; }
		}

		public ModuleManifestType Type
		{
			get { return _type; }
			set { _type = value; }
		}

		public string FileHash { get { return _fileHash; } }

		public ManifestModuleInfo(string name, string guid, Version version, string manifestGuid)
		{
			_name = name;
			_guid = guid;
			_version = version;
			_manifestGuid = manifestGuid;
		}

		public ManifestModuleInfo(string name, string guid, Version version, string culture, string publicKeyToken, string manifestGuid)
		{
			_name = name;
			_guid = guid;
			_version = version;
			_culture = culture;
			_publicKeyToken = publicKeyToken;
			_manifestGuid = manifestGuid;
		}

		public ManifestModuleInfo(XElement moduleElement)
		{
			XAttribute nameAttribute = moduleElement.Attribute("ModuleName");
			Trace.Assert(nameAttribute != null && !String.IsNullOrEmpty(nameAttribute.Value), "Module Name attribute missing");
			_name = nameAttribute.Value;

			XAttribute typeAttribute = moduleElement.Attribute("ModuleType");
			Trace.Assert(typeAttribute != null && !String.IsNullOrEmpty(typeAttribute.Value), "Module Type attribute missing");
			try
			{
				//Console.WriteLine(typeAttribute != null ? typeAttribute.Value : "Module");
				//ModuleType is optional, defaulting it to "Module"
				_type = (ModuleManifestType)Enum.Parse(typeof(ModuleManifestType),
					(typeAttribute != null ? typeAttribute.Value : "Module"));
			}
			catch (Exception ex)
			{
				throw new Exception(String.Format("Unrecognised module Type attribute value '{0}'.", typeAttribute.Value), ex);
			}
			List<ModuleManifestType> manifestTypes =
				new List<ModuleManifestType>()
				{ 
					ModuleManifestType.Application, 
					ModuleManifestType.Shell,
					ModuleManifestType.Module
				};


			XAttribute xFileHash = moduleElement.Attribute("FileHash");
			_fileHash = (xFileHash != null)? xFileHash.Value : String.Empty;
			

			XAttribute guidAttribute = moduleElement.Attribute("Guid");
			if (guidAttribute == null)
				guidAttribute = moduleElement.Attribute("ModuleGuid");

			Trace.Assert(guidAttribute != null && !String.IsNullOrEmpty(guidAttribute.Value), "Module Guid attribute missing");
			_guid = guidAttribute.Value;

			XAttribute versionAttribute = moduleElement.Attribute("Version");
			if (versionAttribute == null)
				versionAttribute = moduleElement.Attribute("ModuleVersion");

			Trace.Assert(versionAttribute != null && !String.IsNullOrEmpty(versionAttribute.Value), "Module Version attribute missing");
			_version = new Version(versionAttribute.Value);

			XAttribute cultureAttribute = moduleElement.Attribute("Culture");
			if (cultureAttribute != null)
				_culture = cultureAttribute.Value;

			XAttribute publicKeyTokenAttribute = moduleElement.Attribute("PublicKeyToken");
			if (publicKeyTokenAttribute != null)
				_publicKeyToken = publicKeyTokenAttribute.Value;

			XAttribute manifestGuidAttribute = moduleElement.Attribute("ManifestGuid");
			if (manifestGuidAttribute == null)
				manifestGuidAttribute = moduleElement.Attribute("ModuleManifestGuid");

			Trace.Assert(manifestGuidAttribute != null && !String.IsNullOrEmpty(manifestGuidAttribute.Value), "Module ManifestGuid attribute missing");
			_manifestGuid = manifestGuidAttribute.Value;

			XAttribute categoryAttribute = moduleElement.Attribute("Category");
			if (categoryAttribute != null)
				_category = categoryAttribute.Value;

			XAttribute descriptionAttribute = moduleElement.Attribute("Description");
			if (descriptionAttribute != null)
				_description = descriptionAttribute.Value;
		}
	}
}
